﻿using System;
using System.Collections.Generic;
using System.Text;
using Common.TextMatch;
using DO.Clustering;

namespace BLL.Relations.VectorDistances
{
    /// <summary>
    /// 
    /// </summary>
    public class FeatureSimilarityMatrix
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Features"></param>
        /// <returns></returns>
        public static Dictionary<int, Dictionary<int, double>> BuildFeatureDistanceMatrixUsingNgram(
            List<Feature> Features)
        {
            Dictionary<int, Dictionary<int, double>> FeatureSimilarityMatrix =
                new Dictionary<int, Dictionary<int, double>>();
            for(int i=0;i<Features.Count;i++)
            {
                string txt1 = Features[i].Name;
                Dictionary<int,double> similarities=new Dictionary<int, double>();
                for(int k=0;k<Features.Count;k++)
                {
                    string txt2 = Features[k].Name;
                    similarities.Add(Features[k].FeatureID, NGramUtil.ComputeNGramSimilarity(txt1,txt2,4));
                }
                FeatureSimilarityMatrix.Add(Features[i].FeatureID,similarities);
            }
            return FeatureSimilarityMatrix;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="FeatureFreqs1"></param>
        /// <param name="FeatureFreqs2"></param>
        /// <returns></returns>
        public static Dictionary<int,Dictionary<int,double>> BuildFeatureDistanceMatrixUsingNgram(
            Dictionary<int,FeatureFreq> FeatureFreqs1, Dictionary<int,FeatureFreq> FeatureFreqs2)
        {
            List<Feature> Features = new List<Feature>();
            List<int> unionFeatureIDs=new List<int>();
            foreach(int FeatureID in FeatureFreqs1.Keys)
            {
                Feature Feature = new Feature();
                Feature.FeatureID = FeatureID;
                Feature.Name = FeatureFreqs1[FeatureID].Name;
                Feature.Weight = FeatureFreqs1[FeatureID].Weight;
                Features.Add(Feature);
                unionFeatureIDs.Add(FeatureID);
            }
            foreach(int FeatureID in FeatureFreqs2.Keys)
            {
                if(!unionFeatureIDs.Contains(FeatureID))
                {
                    Feature Feature = new Feature();
                    Feature.FeatureID = FeatureID;
                    Feature.Name = FeatureFreqs2[FeatureID].Name;
                    Feature.Weight = FeatureFreqs2[FeatureID].Weight;
                    Features.Add(Feature);
                }
            }

            return FeatureSimilarityMatrix.BuildFeatureDistanceMatrixUsingNgram(Features);
        }

        /// <summary>
        /// root word -> list of Feature ids
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string,List<int>> BuildFeatureInflectionalStemmingMappings(List<Feature> Features)
        {
            InflectionalStemmer stemmer=new InflectionalStemmer(); 
            Dictionary<string,List<int>> FeatureStemmings=new Dictionary<string, List<int>>();
            foreach(Feature Feature in Features)
            {
                string[] words = Feature.Name.Split(new char[]{' '});
                foreach(string word in words)
                {
                    string root = stemmer.StemTerm(word).ToLower();
                    if(FeatureStemmings.ContainsKey(root))
                    {
                        List<int> FeatureIDs = FeatureStemmings[root];
                        if(!FeatureIDs.Contains(Feature.FeatureID))
                            FeatureIDs.Add(Feature.FeatureID);
                        FeatureStemmings[root] = FeatureIDs;
                    }
                    else
                    {
                        List<int> FeatureIDs=new List<int>();
                        FeatureIDs.Add(Feature.FeatureID);
                        FeatureStemmings.Add(root,FeatureIDs);
                    }
                }
            }

            return FeatureStemmings;
        }

        /// <summary>
        /// root word -> list of Feature ids
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, List<int>> BuildFeaturePorterStemmingMappings(List<Feature> Features)
        {
            PorterStemmer stemmer = new PorterStemmer();
            Dictionary<string, List<int>> FeatureStemmings = new Dictionary<string, List<int>>();
            foreach (Feature Feature in Features)
            {
                string[] words = Feature.Name.Split(new char[] { ' ' });
                foreach (string word in words)
                {
                    string root = stemmer.StemTerm(word).ToLower();
                    if (FeatureStemmings.ContainsKey(root))
                    {
                        List<int> FeatureIDs = FeatureStemmings[root];
                        if (!FeatureIDs.Contains(Feature.FeatureID))
                            FeatureIDs.Add(Feature.FeatureID);
                        FeatureStemmings[root] = FeatureIDs;
                    }
                    else
                    {
                        List<int> FeatureIDs = new List<int>();
                        FeatureIDs.Add(Feature.FeatureID);
                        FeatureStemmings.Add(root, FeatureIDs);
                    }
                }
            }

            return FeatureStemmings;
        }

    }
}
